#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
Copyright © Devion Team
License: New BSD License
__name__ = "gui.py"
__doc__ = "This file takes care of the graphical user interface"
"""

debug = True

try:
	#import gnome.ui
	#import random
	import gtk
	import pygtk; pygtk.require('2.0')
	import gtk.glade
	import threading
	from boxAPI import *
	import config
	import gtkConfirm
	import trayicon
	import time
	import os
	import sys
	import re
	import webbrowser
except ImportError:
	pass

# What's our process id?
PID = os.getpid()

# This will store current active threads
THREADS = {}

# Initializing gtk's thread engine
gtk.gdk.threads_init()

# Glade generated GTK UI XML file
gladefile = sys.path[0] + '/gui.glade'
# Icons to use
if debug: print ' *** setting tray icon...'
try:
	TRAY_ICON = os.path.join(sys.path[0], 'pixmaps','tray.ico')
	if debug: print ' *** OK'
except:
	if debug: print ' *** Failed'
if debug: print ' *** setting logo pixbuf...'
try:
	LOGO = gtk.gdk.pixbuf_new_from_file(os.path.join(sys.path[0], 'pixmaps','suindara_logo.ico'))
	if debug: print ' *** OK'
except:
	if debug: print ' *** Failed'
if debug: print ' *** setting logo pixbuf...'
try:
	ICON = gtk.gdk.pixbuf_new_from_file(os.path.join(sys.path[0], 'pixmaps','suindara.svg'))
	if debug: print ' *** OK'
except:
	if debug: print ' *** Failed'

# Closes gtk window and stops threads
def main_quit():
	global SetProgressBarThread, PID
	if debug: printDebug(' @ Stopping threads and sending kill signal to PID: %s' % PID)
	SetProgressBarThread.stop()
	config.save_config()
	gtk.main_quit()
	print 'Goodbye!'
	os.popen("kill -9 "+str(PID))

"""
	Let's talk about UI classes:
	As most major dialogs will hold their own classes, these will need to have an 
	event handler, and widget initialization, so most will call on __init__
	init_widgets(). init_vars() will also be used for self vars required in the class
	As the event handler for the classes needs to be called before gtk.main(),
	these are initialized in Application class's __init__.
	Minor dilaogs such as confirmation windows and such are handled inside 'parent'
	dialog's class for more beautifull code.
	btw, because we are not microsoft engineers, we use threading
"""
class Application:
	global config, uixml, b
	# config, where global program options and account data is managed
	config = config.boxConfig()
	# references the xml grabbed from the glade file
	uixml = gtk.glade.XML(gladefile)
	# the box handler class from the boxAPI
	b = boxHandler()

	"""
		Because we will be using different classes for dialogs, and considering
		that threads are also classes, references to dialogs and widgets are 
		made global
	"""
	
	### dialogs
	global d_mainwin; d_mainwin = uixml.get_widget('mainwin')
	global d_about; d_about = uixml.get_widget('aboutdialog')
	global d_register; d_register = uixml.get_widget('register_dialog')
	global d_login; d_login = uixml.get_widget('login_dialog')
	global d_login_other; d_login_other = uixml.get_widget('login_other_dialog')
	global d_account_details; d_account_details = uixml.get_widget('details_dialog')
	global d_remove_dialog; d_remove_dialog = uixml.get_widget('removefolderdialog')
	global d_filechooser_upload; d_filechooser_upload = uixml.get_widget('filechooserdialog')
	global d_exit_confirm; d_exit_confirm = uixml.get_widget('confirmexitdialog')
	global d_add_folder; d_add_folder = uixml.get_widget('add_folder_dialog')
	global d_rename; d_rename = uixml.get_widget('rename_dialog')
	global d_preferences; d_preferences = uixml.get_widget('preferences_dialog')
	global d_downloadsfolderchooser; d_downloadsfolderchooser = uixml.get_widget('downloadsfolderchooser_dialog')
	global d_multifile_upload; d_multifile_upload = uixml.get_widget('multipleupload_dialog')
	### widgets
	## mainwin
	# folder/file browser
	global fb_folderview; fb_folderview = uixml.get_widget('treeview1')
	global fb_fileview; fb_fileview = uixml.get_widget('treeview2')
	# statusbar
	global s_status; s_status = uixml.get_widget('statusbar')
	global s_progress; s_progress = uixml.get_widget('status_progressbar')
	global s_cancel; s_cancel = uixml.get_widget('cancelop_button')
	# menubar
	global wm_connect; wm_connect = uixml.get_widget('connect')
	global wm_disconnect; wm_disconnect = uixml.get_widget('disconnect')
	global wm_new_account; wm_new_account = uixml.get_widget('new_account')
	global wm_account_details; wm_account_details = uixml.get_widget('account_details')
	global wm_quit; wm_quit = uixml.get_widget('quit')
	global wm_preferences; wm_preferences = uixml.get_widget('preferences')
	global wm_add_folder; wm_add_folder = uixml.get_widget('add_folder')
	global wm_remove_folder; wm_remove_folder = uixml.get_widget('remove_folder')
	global wm_upload_file; wm_upload_file = uixml.get_widget('upload_file')
	global wm_download_file; wm_download_file = uixml.get_widget('download_file')
	global wm_delete_file; wm_delete_file = uixml.get_widget('delete_file')
	global wm_move_selected; wm_move_selected = uixml.get_widget('move_selected')
	global wm_rename_selected; wm_rename_selected = uixml.get_widget('rename_selected')
	global wm_refresh_list; wm_refresh_list = uixml.get_widget('refresh_list')
	global wm_help; wm_help = uixml.get_widget('help')
	global wm_about; wm_about = uixml.get_widget('about')
	# toolbar
	global wt_add_folder; wt_add_folder = uixml.get_widget('afolderbutton')
	global wt_delete_folder; wt_delete_folder = uixml.get_widget('dfolderbutton')
	global wt_upload_file; wt_upload_file = uixml.get_widget('ufilebutton')
	global wt_download_file; wt_download_file = uixml.get_widget('dfilebutton')
	global wt_delete_file; wt_delete_file = uixml.get_widget('deletebutton')
	global wt_move_selected; wt_move_selected = uixml.get_widget('movebutton')
	global wt_rename_selected; wt_rename_selected = uixml.get_widget('renamebutton')
	global wt_refresh; wt_refresh = uixml.get_widget('refreshbutton')
	## login
	global l_LoginCombo; l_LoginCombo = uixml.get_widget('l_LoginCombo')
	global l_PasswordEntry; l_PasswordEntry = uixml.get_widget('l_PasswordEntry')
	global l_RememberPasswordCheck; l_RememberPasswordCheck = uixml.get_widget('l_RememberPasswordCheck')
	global l_MakeDefaultCheck; l_MakeDefaultCheck = uixml.get_widget('l_MakeDefaultCheck')
	## login with other account
	global lo_LoginEntry; lo_LoginEntry = uixml.get_widget('lo_LoginEntry')
	## register
	global r_LoginEntry; r_LoginEntry = uixml.get_widget('r_LoginEntry')
	global r_PasswordEntry; r_PasswordEntry = uixml.get_widget('r_PasswordEntry')
	global r_RepeatPasswordEntry; r_RepeatPasswordEntry = uixml.get_widget('r_RepeatPasswordEntry')
	## account details
	global ad_LoginLabel; ad_LoginLabel = uixml.get_widget('ad_LoginLabel')
	global ad_TotalSpaceLabel; ad_TotalSpaceLabel = uixml.get_widget('ad_TotalSpaceLabel')
	global ad_SpaceUsedProgressbar; ad_SpaceUsedProgressbar = uixml.get_widget('ad_SpaceUsedProgressbar')
	## upload dialog
	global ud_qeued_list; ud_qeued_list = uixml.get_widget('qeued_upload_list')
	## file chooser
	#global d_filechooser_upload; d_filechooser_upload = uixml.get_widget('filechooserdialog')
	global fc_files; fc_files = uixml.get_widget('filechooserwidget')
	#global fc_pathlabel; fc_pathlabel = uixml.get_widget('uploadpath_label')
	## remove folder
	global rf_combo; rf_combo = uixml.get_widget('rf_combo')
	global rf_confirm; rf_confirm = uixml.get_widget('rf_confirm')
	## rename file
	global rn_NewNameEntry; rn_NewNameEntry = uixml.get_widget('rn_NewNameEntry')
	## preferences
	global pr_AutoConnectCheck; pr_AutoConnectCheck = uixml.get_widget('pr_AutoConnectCheck')
	global pr_PublicComputerCheck; pr_PublicComputerCheck = uixml.get_widget('pr_PublicComputerCheck')
	global pr_SecureConnectionsCheck; pr_SecureConnectionsCheck = uixml.get_widget('pr_SecureConnectionsCheck')
	global pr_HideToSystemTrayCheck; pr_HideToSystemTrayCheck = uixml.get_widget('pr_HideToSystemTrayCheck')
	global pr_DownloadsFolderButton; pr_DownloadsFolderButton = uixml.get_widget('pr_DownloadsFolderButton')
	global pr_DownloadOverwriteCheck; pr_DownloadOverwriteCheck = uixml.get_widget('pr_DownloadOverwriteCheck')
	# mouse right click menu
	global m1_right_click; m1_right_click = uixml.get_widget('rightclickmenu')
	## add folder
	global af_FolderNameEntry; af_FolderNameEntry = uixml.get_widget('af_FolderNameEntry')
	global af_CreationPathLabel; af_CreationPathLabel = uixml.get_widget('af_CreationPathLabel')

	# what type of viewing will we use in file listing
	global file_viewing; file_viewing = 'LIST'
	# let's load the config from *.conf file
	config.load_config()
	
	def __init__(self):
		self.init_tray()
		self.init_vars()
		self.init_widgets()
		self.init_threads()
		# because MainWindow() contains functions that are needed for global access, specially in threads,
		# lets reference it here
		global cMainWindow; cMainWindow = MainWindow()
		# The event grabber handler (called at __init__) in the following classes needs to be referenced
		# before gtk.main()
		ConnectDialog()
		RegisterDialog()
		UploadDialog()
		PreferencesDialog()
		# autoconnect
		self.autoconnect()
		# guess what
		gtk.main()
		
	def init_tray(self):
		# System tray
		global tray_icon; 
		tray_icon = trayicon.TrayIcon(self.on_trayicon_click)
		tray_icon.set_icon(TRAY_ICON)
		
	def init_widgets(self):
		# The event grabber handler, also used in other classes
		nameFuncMap = {}
		for key in dir(self.__class__):
			nameFuncMap[key] = getattr(self, key)
		uixml.signal_autoconnect(nameFuncMap)
		# setting the icon/logo
		if debug: printDebug('*** Setting mainwin Icon... ')
		try:
			d_mainwin.set_icon(ICON)
			if debug: printDebug('*** Ok')
		except: 
			if debug: printDebug('*** Failed')
		# setting the icon/logo
		if debug: printDebug('*** Setting about Logo...')
		try:
			d_about.set_logo(LOGO)
			if debug: printDebug('*** Ok')
		except: 
			if debug: printDebug('*** Failed')
			
	def init_vars(self):
		global currSProgressbarState,connection_is_active,account_info,selected_folder,active_selected,active_selected_lock
		# Status bar's progress bar. As progressbar is handler through a continously
		# running thread, currSProgressbarState is passed, arg1 is percentage [0.0;1.0]
		# arg2 is text to be displayed
		currSProgressbarState = [0.0, 'Disconnected']
		# Indicates if fake connection is active
		connection_is_active = 0
		# Dict stores *CURRENT* account information, app wide account info stored in config
		account_info = {}
		# Currently selected folder ['name', id]
		selected_folder = ['<b>MyBox</b>', '0']
		# Returns active selected, 'None', 'folder' or 'file'
		active_selected = None
		# A lock for active selected
		active_selected_lock = False

	def init_threads(self):
		global SetProgressBarThread
		# We will be starting application wide threads
		SetProgressBarThread = SetProgressBar()
		SetProgressBarThread.start()

	def on_trayicon_click(self, signal, event):
		if event.button==1:
			if d_mainwin.flags() & gtk.VISIBLE:
				d_mainwin.hide()
			else:
				d_mainwin.show()
		else:
			pass
	
	def autoconnect(self):
		if config.get_goption(3) == 1:
			if config.get_goption(1) != 'None':
				global login; login = config.get_goption(1)
				global passwd; passwd = config.get_option(config.get_goption(1), 1)
				ConnectThread = Connect()
				ConnectThread.start()
		else: pass

class MainWindow:
	def __init__(self):
		self.init_vars()
		self.init_widgets()
		
	def init_vars(self):
		self.files_by_pid = {}
		global THREADS
		global parent; parent = self
		self.move_toggled = False

	def init_widgets(self):
		nameFuncMap = {}
		for key in dir(self.__class__):
			nameFuncMap[key] = getattr(self, key)
		uixml.signal_autoconnect(nameFuncMap)
	
		d_mainwin.connect('delete_event', self.on_mainwin_close )
		d_about.connect('delete_event', self.d_about_close )
		d_register.connect('delete_event', self.d_register_close )
		d_login.connect('delete_event', self.d_login_close )
		d_login_other.connect('delete_event', self.d_login_other_close )
		d_account_details.connect('delete_event', self.d_account_details_close )
		d_remove_dialog.connect('delete_event', self.d_remove_dialog_close )
		d_filechooser_upload.connect('delete_event', self.d_filechooser_upload_close )
		d_exit_confirm.connect('delete_event', self.d_exit_confirm_close )
		d_add_folder.connect('delete_event', self.d_add_folder_close )
		d_rename.connect('delete_event', self.d_rename_close )
		d_preferences.connect('delete_event', self.d_preferences_close )
		d_downloadsfolderchooser.connect('delete_event', self.d_downloadsfolderchooser_close )
		d_multifile_upload.connect('delete_event', self.d_multifile_upload_close )
		
		# selected folder in treeview1 (folders)
		selected_folder = ['', '']
		self.init_folderview()
		self.init_fileview()
		
		# attaching right click to treeview1 (folders)
		#m1_right_click.attach_to_widget(fb_folderview, None)
		#m1_right_click.popup(None, None, None, 3, 3)
		self.disconnected()
		
	def init_folderview(self):
		# create a TreeStore with one string column to use as the model
		renderer=gtk.CellRendererText()
		self.folderstore = gtk.TreeStore(str)
		fb_folderview.set_model(self.folderstore)
		# Show treeview headers?
		fb_folderview.set_headers_visible(True)
		column=gtk.TreeViewColumn("Folder",renderer, text=0)
		column.set_attributes(renderer, markup=0)
		column.set_resizable(True)
		fb_folderview.append_column(column)
		
	def init_fileview(self):
		## Mainwin Fileview
		# create a TreeStore with three string column to use as the model
		self.filestore = gtk.TreeStore(gtk.gdk.Pixbuf,str,str,str)
		fb_fileview.set_model(self.filestore)
		# Show treeview headers?
		fb_fileview.set_headers_visible(True)
		# File Column
		renderer = gtk.CellRendererText()
		column = gtk.TreeViewColumn()
		column.set_title('File')
		column.set_resizable(True)
		column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
		column.set_fixed_width(230)
		fb_fileview.append_column(column)
		# Include a pixbuf in the File Column
		renderer = gtk.CellRendererPixbuf()
		column.pack_start(renderer, expand=False)
		column.add_attribute(renderer, 'pixbuf', 0)
		renderer = gtk.CellRendererText()
		column.pack_start(renderer, expand=True)
		column.add_attribute(renderer, 'text', 1)
		# Other info Columns; Size, Date
		column=gtk.TreeViewColumn("Size",renderer, text=2)
		column.set_resizable(True)
		column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
		column.set_fixed_width(60)
		fb_fileview.append_column(column)
		column=gtk.TreeViewColumn("Date Modified",renderer, text=3)
		column.set_resizable(True)
		column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
		column.set_fixed_width(100)
		fb_fileview.append_column(column)
		
	def online_menubar(self):
		# This is how the menubar looks when online 
		# gtk.gdk.threads_enter() <- TODO: delete this? 
		wm_connect.hide()
		wm_disconnect.show()
		wm_account_details.set_sensitive(True)
		wm_add_folder.set_sensitive(True)
		wm_remove_folder.set_sensitive(True)
		wm_upload_file.set_sensitive(True)
		wm_download_file.set_sensitive(True)
		wm_move_selected.set_sensitive(True)
		wm_rename_selected.set_sensitive(True)
		wm_delete_file.set_sensitive(True)
		wm_refresh_list.set_sensitive(True)
		gtk.gdk.threads_leave()
		
	def offline_menubar(self):
		# This is how the menubar looks when offline
		if connection_is_active == 0: 
			wm_connect.show()
			wm_disconnect.hide()
		wm_account_details.set_sensitive(False)
		wm_add_folder.set_sensitive(False)
		wm_remove_folder.set_sensitive(False)
		wm_upload_file.set_sensitive(False)
		wm_download_file.set_sensitive(False)
		wm_move_selected.set_sensitive(False)
		wm_rename_selected.set_sensitive(False)
		wm_delete_file.set_sensitive(False)
		wm_refresh_list.set_sensitive(False)
		
	def online_toolbar(self):
		# This is how the toolbar looks when online
		gtk.gdk.threads_enter()
		wt_add_folder.set_sensitive(True)
		wt_delete_folder.set_sensitive(True)
		wt_upload_file.set_sensitive(True)
		wt_download_file.set_sensitive(True)
		wt_move_selected.set_sensitive(True)
		wt_rename_selected.set_sensitive(True)
		wt_delete_file.set_sensitive(True)
		wt_refresh.set_sensitive(True)
		gtk.gdk.threads_leave()

	def offline_toolbar(self):
		# This is how the toolbar looks when offline 
		wt_add_folder.set_sensitive(False)
		wt_delete_folder.set_sensitive(False)
		wt_upload_file.set_sensitive(False)
		wt_download_file.set_sensitive(False)
		wt_move_selected.set_sensitive(False)
		wt_rename_selected.set_sensitive(False)
		wt_delete_file.set_sensitive(False)
		wt_refresh.set_sensitive(False)

	def online_views(self):
		# This is how the folder and file views look online
		gtk.gdk.threads_enter()
		fb_folderview.set_sensitive(True)
		fb_fileview.set_sensitive(True)
		gtk.gdk.threads_leave()

	def offline_views(self):
		# This is how the folder and file views look offline
		fb_folderview.set_sensitive(False)
		fb_fileview.set_sensitive(False)

	def folder_selected(self, path=None):
		if not path:
			if debug: printDebug('We don\'t have the path')
			return
		#if debug: printDebug('* folder_selected * current path: %s' % path)
		#fc_pathlabel.set_label(self.get_folder_from_path(path)[0])
		af_CreationPathLabel.set_label('Adding folder in: %s' % self.get_folder_from_path(path)[0])
		model = self.folderstore
		if self.files_by_pid:
			for id in self.folderIter_ids:
				if model.get_path(self.folderIter_ids[id]) == path:
					if debug: printDebug('* folder_selected * ITERING')
					return self.display_files_for_id(id)
		
	def get_folder_from_path(self, path=None):
		if not path: return None
		model = self.folderstore
		for id in self.folderIter_ids:
			if model.get_path(self.folderIter_ids[id]) == path:
				folder_id = id
				iter = model.get_iter(path)
				folder = model.get_value(iter, 0)
				break
		return (folder, folder_id)
	
	def display_files_for_id(self, fid=None):
		""" This will dump files from the given folder id.
				Default is 0 if no id is provided
		"""
		if debug: printDebug('* display_files_for_id * Init')
		model = self.filestore
		model.clear()
		if not fid: fid = '0'
		files = self.get_files_for_folderId(fid)
		if files:
			for f in files:
				size, pot = bytes_to_kbytes(float(f.size),1)
				updated = time.asctime(time.localtime(float(f.updated)))
				if debug: printDebug('File: %s / %s' % (f.name, f.thumbnail))
				thumb = gtk.gdk.pixbuf_new_from_file(b.getThumbnail(f.thumbnail))
				model.append(None, [thumb, f.name, '%s%s' % (size, pot), updated])
			if debug: printDebug('* display_files_for_id * Ok')

	def get_files_for_folder(self, folder=None):
		if debug: printDebug('* get_files_for_folder* ...listing files for: %s' % folder)
		# folder = string name
		print '...listing files for: %s' % folder
		for f in self.folders:
			if f.name == folder: fid = f.id
		if self.files_by_pid.has_key(fid):
			return self.files_by_pid[fid]
		else: return None

	def get_files_for_folderId(self, fid=None):
		#if debug: printDebug('* get_files_for_folderId * ...listing files for %s' % fid)
		if self.files_by_pid.has_key(fid):
			if debug: printDebug('* get_files_for_folderId * there are files for this id')
			return self.files_by_pid[fid]
		else: return None

	def refresh_folderList(self, currentFolder=None):
		gtk.gdk.threads_enter()
		if debug: printDebug('...refreshing folder list')
		model = self.folderstore
		model.clear()
		otank = {}
		if connection_is_active:
			if debug: printDebug('Connection is active')
			# get list of folders on our box
			gtk.gdk.threads_leave()
			try:
				self.folders = b.parseFolderList()
				gtk.gdk.threads_enter()
				for f in self.folders:
					if f.parent_id=='na': 
						otank[f.id] = model.append(None, ['<b>%s</b>' % f.name] )
					else: 
						otank[f.id] = model.append(otank[f.parent_id], ['%s' % f.name] )
				if otank:
					self.folderIter_ids = otank
					if debug: printDebug('Selected folder is: %s' % str(selected_folder))
					path = model.get_path(otank['0'])
					#if selected_folder[1] != '':
					#else: 
					#	path = model.get_path(otank['0'])
					fb_folderview.expand_row(path, False)
					self.folder_selected(path)
				gtk.gdk.threads_leave()
			except:
				gtk.gdk.threads_leave()
				self.failed('Failed to refresh folder list')
		gtk.gdk.threads_leave()
	
	def refresh_fileList(self, currentFolder=None):
		gtk.gdk.threads_enter()
		if debug: printDebug('...refreshing file list')
		#model = self.filestore
		#model.clear()
		otank = {}
		if connection_is_active:
			if debug: printDebug('*** Refreshing file list...')
			# get list of files on our box
			gtk.gdk.threads_leave()
			try:
				sel_folder = selected_folder[1]
				self.files = b.parseFileList()
				gtk.gdk.threads_enter()
				a= []; first = 1; self.files_by_pid = {}
				for f in self.files:
					if first:
						pid = f.parent_id
						a.append(f)
						first -= 1
					else:
						if f.parent_id != pid:
							self.files_by_pid[pid] = a
							a = []
						a.append(f)
						pid = f.parent_id
				if self.files_by_pid != {}:
					self.files_by_pid[pid] = a
				
				if file_viewing == 'LIST':
					self.display_files_for_id(sel_folder)
				if debug: printDebug('*** Ok')
				gtk.gdk.threads_leave()
			except:
				gtk.gdk.threads_leave()
				self.failed(' *** Failed')
		gtk.gdk.threads_leave()

	def connected(self):
		global account_info, selected_file
		self.online_menubar()
		self.online_toolbar()
		self.online_views()
		global tray_icon; tray_icon.set_tooltip('Suindara: %s' % account_info['login'])
		selected_file = None
		s_status.push(0,"Connected as: %s" % account_info['login'])
		# set account details values
		ad_LoginLabel.set_label(account_info['login'])
		amount = str(int(account_info['space_amount']) /1024/1024)
		ad_TotalSpaceLabel.set_label('%s MB' % (amount))
		if account_info['space_used'] == None: 
			mbused = 0.0
			used = 0
			percent = 0
			fraction = 0
		else: 
			mbused = int(account_info['space_used']) /1024/1024.0
			used = str(mbused).split('.')[0] + '.' + str(mbused).split('.')[1][0]
			percent = str(int(account_info['space_used']) *100.0 / int(account_info['space_amount']))[:4]
			fraction = int(percent.split('.')[0]) /100.0
		if debug: printDebug('Percentage of storage used: ' + str(percent))
		if debug: printDebug(fraction)
		# Used space in account details dialog
		ad_SpaceUsedProgressbar.set_text('%s MB (%s%%)' % (used, percent))
		ad_SpaceUsedProgressbar.set_fraction(fraction)

	def disconnect(self):
		# What to do when we disconnect
		self.disconnected()
		#self.refresh_folderList()
		#self.refresh_fileList()

	def disconnected(self):
		global currSProgressbarState, connection_is_active
		connection_is_active = 0
		# How some stuff gets when we're disconnected
		self.offline_menubar()
		self.offline_toolbar()
		self.offline_views()
		global tray_icon; tray_icon.set_tooltip('Suindara: Not Connected')
		s_status.push(0,"To start, choose Connect from the Storage menu")
		currSProgressbarState = [0.0, 'Not connected']
		selected_folder = ['', '']

	def failed(self, text, todo=None):
		if not text:
			return
		global currSProgressbarState; currSProgressbarState = [0.0, text]
		if todo == 'disconnect': self.disconnect

	## Menubar callbacks
	### 'Storage' menu
	def on_connect_activate(self, widget):
		d_login.show()

	def on_disconnect_activate(self, widget):
		# This is a fake disconnect (for now)
		self.disconnect()
		
	def on_new_account_activate(self, widget):
		# we'll hide this for now...
		#d_register.show()
		webbrowser.open( "http://www.shareasale.com/r.cfm?B=35484&U=175990&M=7803",new=2, autoraise=1)

	def on_account_details_activate(self, widget):
		d_account_details.show()
		
	def on_quit_activate(self, widget):
		if connection_is_active:
			d_exit_confirm.show()
		else:
			main_quit()
	### 'Tools' menu
	def on_add_folder_activate(self, widget):
		af_FolderNameEntry.set_text('')
		d_add_folder.show()
				
	def on_remove_folder_activate(self, widget):
		if selected_folder[1] != '' and gtkConfirm.confirm('Do you realy want to delete <b>%s</b>?\nAll files/folders in it will be deleted.' %selected_folder[0], d_mainwin):
			RemoveFolderThread = RemoveFolder()
			RemoveFolderThread.start()		

	def on_upload_file_activate(self, widget):
		d_multifile_upload.show()
		
	def on_download_file_activate(self, widget):
		setThread('Download',DownloadFile())
		THREADS["Download"].start()
		
	def on_delete_file_activate(self, widget):
		if gtkConfirm.confirm('Are you sure you want to remove <b>%s</b>?' % str(selected_file.name), d_mainwin):
			DeleteFileThread = DeleteFile()
			DeleteFileThread.start()
			
	def on_move_selected_activate(self, widget):
		if wt_move_selected.get_active():
			wt_move_selected.set_active(False)
		else:
			wt_move_selected.set_active(True)

	def on_rename_selected_activate(self, widget):
		if active_selected != None:
			rn_NewNameEntry.set_text('')
			if active_selected == 'file': 
				print 'selected_file is ' + str(selected_file.name)
				d_rename.set_title('Rename file %s' % selected_file.name)
			elif active_selected == 'folder': 
				d_rename.set_title('Rename folder %s' % str(selected_folder[0]))
			d_rename.show()
		else: gtkConfirm.message_error('You need to select a file or folder to rename', d_mainwin)

	def on_refresh_list_activate(self, widget):
		self.offline_menubar()
		self.offline_toolbar()
		RefreshAllThread = RefreshAll()
		RefreshAllThread.start()

	def on_preferences_activate(self, widget):
		d_preferences.show()
		
	### 'Tools' menu
	def on_upgrade_storage_space_activate(self, widget):
		webbrowser.open( "http://www.shareasale.com/r.cfm?B=35484&U=175990&M=7803",new=2, autoraise=1)

	### 'Help' menu
	def on_help_activate(self, widget):
		webbrowser.open( "http://forum.devion.org",new=2, autoraise=1)

	def on_about_activate(self, widget):
		d_about.show()

	## Toolbar callbacks
	def on_afolderbutton_clicked(self, widget):
		af_FolderNameEntry.set_text('')
		d_add_folder.show()

	def on_dfolderbutton_clicked(self, widget):
		if selected_folder[1] != '' and gtkConfirm.confirm('Do you realy want to delete <b>%s</b>?\nAll files/folders in it will be deleted.' %selected_folder[0], d_mainwin):
			RemoveFolderThread = RemoveFolder()
			RemoveFolderThread.start()			

	def on_ufilebutton_clicked(self, widget):
		d_multifile_upload.show()

	def on_downloadButton_clicked(self, widget):
		if active_selected == 'file':
			#DownloadFileThread = DownloadFile()
			#DownloadFileThread.start()
			setThread('DownloadFile',DownloadFile())
			THREADS["DownloadFile"].start()
		elif active_selected == 'folder': 
			DF = DownloadFolder()
			DF.folder = selected_folder
			DF.start()

	def on_deletebutton_clicked(self, widget):
		if gtkConfirm.confirm('Are you sure you want to remove <b>%s</b>?' % str(selected_file.name), d_mainwin):
			DeleteFileThread = DeleteFile()
			DeleteFileThread.start()

	def on_movebutton_toggled(self, widget):
		global active_selected_lock, prev_selected_folder
		if selected_file != None or selected_folder != None:
			if active_selected == 'file':
				if wt_move_selected.get_active():
					#global active_selected_lock
					active_selected_lock = True
					gtkConfirm.message('Now select a folder and press the button again to move the selected file there.', d_mainwin)
				else:
					MoveFileThread = MoveFile()
					MoveFileThread.start()
			elif active_selected == 'folder':
				if wt_move_selected.get_active():
					#global active_selected_lock; 
					active_selected_lock = True
					prev_selected_folder = selected_folder
					gtkConfirm.message('Now select a folder and press the button again to move the selected folder there.', d_mainwin)
				else:
					MoveFolderThread = MoveFolder()
					MoveFolderThread.start()
		else: 
			if wt_move_selected.get_active():
				wt_move_selected.set_active(False)
				gtkConfirm.message_error('You need to select a file to move', d_mainwin)
				
	def on_renamebutton_clicked(self, widget):
		if active_selected != None:
			rn_NewNameEntry.set_text('')
			if active_selected == 'file': 
				print 'selected_file is ' + str(selected_file.name)
				d_rename.set_title('Rename file %s' % selected_file.name)
			elif active_selected == 'folder': d_rename.set_title('Rename folder %s' % str(selected_folder[0]))
			d_rename.show()
		else: gtkConfirm.message_error('You need to select a file or folder to rename', d_mainwin)

	def on_refreshbutton_clicked(self, widget):
		RefreshAllThread = RefreshAll()
		RefreshAllThread.start()
		
	## mouse button click
	def on_treeview1_button_press_event(self, treeview, event):
		global active_selected, selected_folder
		if event.button == 1: # left button
			if active_selected_lock != True:
				active_selected = 'folder'
			x = int(event.x)
			y = int(event.y)
			if debug: printDebug('TREEVIEW: left click received @ (%s,%s)' % (x,y))
			pthinfo = treeview.get_path_at_pos(x, y)
			if pthinfo != None:
				if debug: printDebug(pthinfo)
				path, col, cellx, celly = pthinfo
				treeview.grab_focus()
				treeview.set_cursor( path, col, 0)
				model = treeview.get_model()
				iter = model.get_iter(path)
				value = model.get_value(iter, 0)
				content = model[iter]
				selected_folder = self.get_folder_from_path(path)
				self.folder_selected(path)	
				if debug: printDebug('selected_folder is ' + str(selected_folder))
		if event.button == 3: # right button
			active_selected = 'folder'
			x = int(event.x)
			y = int(event.y)
			if debug: printDebug('TREEVIEW: right click received @ (%s,%s)' % (x,y))
			pthinfo = treeview.get_path_at_pos(x, y)
			if pthinfo != None:
				if debug: printDebug(pthinfo)
				path, col, cellx, celly = pthinfo
				treeview.grab_focus()
				treeview.set_cursor( path, col, 0)
				model = treeview.get_model()
				iter = model.get_iter(path)
				value = model.get_value(iter, 0)
				content = model[iter]
				print "Row value : %s" % content
			
	def on_treeview2_button_press_event(self, treeview, event):
		global active_selected, selected_file
		if event.button == 1: # left button
			if active_selected_lock != True:
				active_selected = 'file'
			x = int(event.x)
			y = int(event.y)
			if debug: printDebug('ICONVIEW: left click received @ (%s,%s)' % (x,y))
			pthinfo = treeview.get_path_at_pos(x, y)
			if pthinfo != None:
				if debug: printDebug(pthinfo)
				path, col, cellx, celly = pthinfo
				treeview.grab_focus()
				treeview.set_cursor( path, col, 0)
				model = treeview.get_model()
				iter = model.get_iter(path)
				content = model[iter]
				if debug: printDebug('Row value : %s' % content)
				if debug: printDebug('selected_folder is ' + str(selected_folder))
				folder = selected_folder[1]
				files = self.get_files_for_folderId(folder)
				if debug: printDebug(files)
				selectedFile = str(pthinfo[0]).split(',')[0].split('(')[1]
				print selectedFile
				selected_file = files[int(selectedFile)]
				if debug: printDebug(selected_file)
		if event.button == 3: # right button
			active_selected = 'file'
			x = int(event.x)
			y = int(event.y)
			if debug: printDebug('ICONVIEW: right click received @ (%s,%s)' % (x,y))
			pthinfo = treeview.get_path_at_pos(x, y)
			if pthinfo != None:
				if debug: printDebug(pthinfo)
				path, col, cellx, celly = pthinfo
				treeview.grab_focus()
				treeview.set_cursor( path, col, 0)
				model = treeview.get_model()
				iter = model.get_iter(path)
				content = model[iter]
				print "Row value : %s" % content
				
	def on_cancelop_button_clicked(self, widget):
		# This will ONLY cancel download/upload operations for now
		if gtkConfirm.confirm('Are you sure you want to cancel the current operation?', d_mainwin):
			THREADS[THREADS['active']].cancel()
	
	# Account details dialog
	def ac_update(self):
		global account_info
		print 'AC UPDATE USADO: ' + str(account_info['space_used']) 
		mbused = int(account_info['space_used']) /1024/1024.0
		print mbused
		used = str(mbused).split('.')[0] + '.' + str(mbused).split('.')[1][0]
		print used
		percent = str(int(account_info['space_used']) *100.0 / int(account_info['space_amount']))[:4]
		print percent
		fraction = int(percent.split('.')[0]) /100.0
		print fraction
		gtk.gdk.threads_enter()
		ad_SpaceUsedProgressbar.set_text('%s MB (%s%%)' % (used, percent))
		ad_SpaceUsedProgressbar.set_fraction(fraction)
		gtk.gdk.threads_leave()

	def on_adCloseButton_clicked(self, widget):
		d_account_details.hide()
		
	def on_detailsdialog_destroy(self, widget):
		d_account_details.hide()

	# Add folder dialog
	def on_afAddButton_clicked(self, widget):
		if selected_folder[1] != '':
			AddFolderThread = AddFolder()
			AddFolderThread.start()
		d_add_folder.hide()
	
	def on_afCancelButton_clicked(self, widget):
		d_add_folder.hide()
		
	#def on_addfolder_destroy(self, widget):
	#	d_add_folder.hide()
		
	# Rename file dialog
	def on_rnRenameButton_clicked(self, widget):
		if rn_NewNameEntry.get_text() != '':
			d_rename.hide()
			if active_selected == 'file':
				RenameThread = RenameFile()
				RenameThread.start()
			elif active_selected == 'folder':
				RenameThread = RenameFolder()
				RenameThread.start()
			
	def on_rnCancelButton_clicked(self, widget):
		d_rename.hide()
		
	# Hide mainwin instead of destroying it
	def on_mainwin_close(self, *args):
		if config.get_goption(8) == 1:
			if debug: printDebug('*** Will minimize to tray if closed')
			d_mainwin.hide()
			return gtk.TRUE
		elif config.get_goption(8) == 0:
			main_quit()
			
	def d_about_close(self, *args):
		d_about.hide()
		return gtk.TRUE
	def d_register_close(self, *args):
		d_about.hide()
		return gtk.TRUE
	def d_login_close(self, *args):
		d_login.hide()
		return gtk.TRUE
	def d_login_other_close(self, *args):
		d_login_other.hide()
		return gtk.TRUE
	def d_account_details_close(self, *args):
		d_account_details.hide()
		return gtk.TRUE
	def d_remove_dialog_close(self, *args):
		d_remove_dialog.hide()
		return gtk.TRUE
	def d_filechooser_upload_close(self, *args):
		d_filechooser_upload.hide()
		return gtk.TRUE
	def d_exit_confirm_close(self, *args):
		d_exit_confirm.hide()
		return gtk.TRUE
	def d_add_folder_close(self, *args):
		d_add_folder.hide()
		return gtk.TRUE
	def d_rename_close(self, *args):
		d_rename.hide()
		return gtk.TRUE
	def d_preferences_close(self, *args):
		d_preferences.hide()
		return gtk.TRUE
	def d_downloadsfolderchooser_close(self, *args):
		d_downloadsfolderchooser.hide()
		return gtk.TRUE
	def d_multifile_upload_close(self, *args):
		d_multifile_upload.hide()
		return gtk.TRUE
	
	# Confirm exit dialog
	def on_quitcancelbutton_clicked(self, widget):
		d_exit_confirm.hide()
		
	def on_quitconfirmbutton_clicked(self, widget):
		config.save_config()
		main_quit()

class ConnectDialog: # This also includes "Login with other account" as it is a sub-dialog 
	def __init__(self):
		self.init_vars()
		self.init_widgets()	

	def init_vars(self):
		self.refresh_on_change = 1

	def init_widgets(self):
		nameFuncMap = {}
		for key in dir(self.__class__):
			nameFuncMap[key] = getattr(self, key)
		uixml.signal_autoconnect(nameFuncMap)

		l_RememberPasswordCheck.set_sensitive(False)
		l_MakeDefaultCheck.set_sensitive(False)
		self.do_lLoginCombo_refill()

	# Connect dialog
	def on_lLoginButton_clicked(self, widget):
		global ConnectThread
		global login; login = l_LoginCombo.get_active_text()
		global passwd; passwd = l_PasswordEntry.get_text()
		if l_RememberPasswordCheck.get_active():
			config.set_option(login, 1, passwd)
		ConnectThread = Connect()
		ConnectThread.start()
		d_login.hide() 

	def on_lLoginCombo_changed(self, widget):
		if l_LoginCombo.get_active_text() == 'Other':
			d_login_other.show()
		elif self.refresh_on_change == 1:
			l_RememberPasswordCheck.set_sensitive(True)
			l_MakeDefaultCheck.set_sensitive(True)
			if int(config.get_option(l_LoginCombo.get_active_text(), 2)) == 1:
				if l_RememberPasswordCheck.get_active() == False:
					l_RememberPasswordCheck.set_active(True)
				l_PasswordEntry.set_text(config.get_option(l_LoginCombo.get_active_text(), 1))
			else:
				if l_RememberPasswordCheck.get_active() == True:
					l_RememberPasswordCheck.set_active(False)
				l_PasswordEntry.set_text('')
			if config.get_goption(1) == l_LoginCombo.get_active_text():
				l_MakeDefaultCheck.set_active(True)
			else:
				l_MakeDefaultCheck.set_active(False)
		else:
			self.refresh_on_change = 1			
			pass	

	def on_lRememberPasswordCheck_toggled(self, widget):
		if l_RememberPasswordCheck.get_active():
			config.set_option(str(l_LoginCombo.get_active_text()), 2, 1)
		else:
			config.set_option(str(l_LoginCombo.get_active_text()), 2, 0)

	def on_lMakeDefaultCheck_toggled(self, widget):
		if l_MakeDefaultCheck.get_active():
			config.set_goption(1, l_LoginCombo.get_active_text())
			if debug: printDebug('Default account is: ' + config.get_goption(1))
		else:
			config.set_goption(1, 'None')
			if debug: printDebug('Default account is: ' + config.get_goption(1))

	def on_lCancelButton_clicked(self, widget):
		d_login.hide()
		
	def on_logindialog_close(self, widget):
		if debug: printDebug('login dialog destroy event detected')
		d_login.hide()

	def do_lLoginCombo_refill(self):
		k = 0
		r = None
		for account in config.get_accounts():
			l_LoginCombo.append_text(account)
			if str(account) == config.get_goption(1):
				r = k
			k+=1
		l_LoginCombo.append_text('Other')
		if r != None:
			l_RememberPasswordCheck.set_sensitive(True)
			l_MakeDefaultCheck.set_sensitive(True)
			l_LoginCombo.set_active(r)

	# Login with other account dialog
	def on_loSaveAndUse_clicked(self, widget):
		l_LoginCombo.insert_text(config.get_int_accounts(), lo_LoginEntry.get_text())
		l_LoginCombo.set_active(config.get_int_accounts())
		l_RememberPasswordCheck.set_sensitive(True)
		l_MakeDefaultCheck.set_sensitive(True)
		config.set_option(str(lo_LoginEntry.get_text()), 0, str(lo_LoginEntry.get_text())) 
		l_PasswordEntry.set_text(config.get_option(l_LoginCombo.get_active_text(), 1))
		if l_RememberPasswordCheck.get_active() == True:
			l_RememberPasswordCheck.set_active(False)
		d_login_other.hide()
	
	def on_loCancelButton_clicked(self, widget):
		self.refresh_on_change = 0
		l_LoginCombo.set_active(-1)
		d_login_other.hide()
		
	def on_loginotherdialog_destroy(self, widget):
		d_login_other.hide()

class RegisterDialog:
	def __init__(self):
		self.init_widgets()	

	def init_widgets(self):
		nameFuncMap = {}
		for key in dir(self.__class__):
			nameFuncMap[key] = getattr(self, key)
		uixml.signal_autoconnect(nameFuncMap)

	def on_rRegisterButton_clicked(self, widget):
		login = r_LoginEntry.get_text()
		passwd = r_PasswordEntry.get_text()
		passwd2 = r_RepeatPasswordEntry.get_text()
		if passwd == passwd2:
			b.register(login, passwd)
			d_register.hide()
		else: d_register.hide() 

	def on_rCancelButton_clicked(self, widget):
		d_register.hide()	
		
	def on_registerdialog_destroy(self, widget):
		d_register.hide()

class UploadDialog:
	def __init__(self):
		self.init_widgets()
		self.qeued_list = []
		global THREADS

	def init_widgets(self):
		## Multiple-File Upload Fileview
		# We'll have just two columns here; File, Size
		self.uploadstore = gtk.TreeStore(str,str)
		ud_qeued_list.set_model(self.uploadstore)
		ud_qeued_list.set_headers_visible(True)
		renderer = gtk.CellRendererText()
		# File Column
		column = gtk.TreeViewColumn("File",renderer, text=0)
		column.set_resizable(True)
		column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
		column.set_fixed_width(170)
		ud_qeued_list.append_column(column)
		# Size Column
		column = gtk.TreeViewColumn("Size",renderer, text=1)
		column.set_resizable(True)
		column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
		column.set_fixed_width(60)
		ud_qeued_list.append_column(column)
		nameFuncMap = {}
		
		for key in dir(self.__class__):
			nameFuncMap[key] = getattr(self, key)
		uixml.signal_autoconnect(nameFuncMap)
		
	def refresh_qeued_list(self):
		model = self.uploadstore
		model.clear()
		if self.qeued_list:
			for f in self.qeued_list:
				size, pot = bytes_to_kbytes(float(os.path.getsize(f)),1)
				file = os.path.split(f)[1]
				if debug: printDebug(' ++ %s - %s%s' % (file, size, pot))
				model.append(None, [file, '%s%s' % (size, pot)])
			if debug: printDebug('* refresh_qeued_list * Ok')
		
	# File chooser events
	def on_upload_cancelbutton_clicked(self, widget):
		d_filechooser_upload.hide()
		
	def on_upload_addbutton_clicked(self, widget):
		file_to_add = fc_files.get_filename()
		# Check if selected item is a file...
		try:
			open(file_to_add,'r').close()
			if debug: printDebug('FILE: %s' % file_to_add)
			self.qeued_list.append(file_to_add)
			d_filechooser_upload.hide()
			self.refresh_qeued_list()
		#Or a folder..?
		except:
			if debug: printDebug('FOLDER: %s' % file_to_add)
		
	# Upload dialog events
	def on_ufAddButton_clicked(self, widget):
		d_filechooser_upload.show()
		
	def on_ufRemoveButton_clicked(self, widget):
		if self.path:
			index = re.search('\d', str(self.path)).group(0)
			self.qeued_list.remove(self.qeued_list[int(index)])
			self.refresh_qeued_list()
		
	def on_ufUploadButton_clicked(self, widget):
		if self.qeued_list:
			if debug: printDebug(' * Starting upload...')
			setThread('Upload',Upload(self.qeued_list))
			THREADS["Upload"].start()
			d_multifile_upload.hide()
		else:
			if debug: printDebug(' * No files in qeue to upload...')
		
	def on_ufCancelButton_clicked(self, widget):
		d_multifile_upload.hide()
		
	def on_qeuedList_button_press_event(self, treeview, event):
		global active_selected, selected_file
		if event.button == 1: # left button
			x = int(event.x)
			y = int(event.y)
			if debug: printDebug('QEUED: left click received @ (%s,%s)' % (x,y))
			pthinfo = treeview.get_path_at_pos(x, y)
			if pthinfo != None:
				if debug: printDebug(pthinfo)
				self.path, col, cellx, celly = pthinfo
				treeview.grab_focus()
				treeview.set_cursor( self.path, col, 0)
				model = treeview.get_model()
				selected_iter = model.get_iter(self.path)
				content = model[selected_iter]
				if debug: printDebug('Row value : %s' % content)
				if debug: printDebug('selected_folder is ' + str(selected_folder))
				folder = selected_folder[1]
				selectedFile = (str(pthinfo[0]).split(',')[0]).split('(')[1]
		if event.button == 3: # right button
			x = int(event.x)
			y = int(event.y)
			if debug: printDebug('ICONVIEW: right click received @ (%s,%s)' % (x,y))
			pthinfo = treeview.get_path_at_pos(x, y)
			if pthinfo != None:
				if debug: printDebug(pthinfo)
				path, col, cellx, celly = pthinfo
				treeview.grab_focus()
				treeview.set_cursor( path, col, 0)
				model = treeview.get_model()
				iter = model.get_iter(path)
				content = model[iter]
				if debug: printDebug("Row value : %s" % content)
		
class PreferencesDialog: # downloads folder chooser dialog stuff included
	def __init__(self):
		self.init_widgets()	

	def init_widgets(self):
		nameFuncMap = {}
		for key in dir(self.__class__):
			nameFuncMap[key] = getattr(self, key)
		uixml.signal_autoconnect(nameFuncMap)
		if config.get_goption(3) == 1: pr_AutoConnectCheck.set_active(True)
		if config.get_goption(4) == 1: pr_PublicComputerCheck.set_active(True)
		if config.get_goption(5) == 1: pr_SecureConnectionsCheck.set_active(True)
		pr_DownloadsFolderButton.set_label(str(config.get_goption(6)))
		if config.get_goption(7) == 1: pr_DownloadOverwriteCheck.set_active(True)
		if config.get_goption(8) == 1: pr_HideToSystemTrayCheck.set_active(True)

	def on_prAutoConnectCheck_toggled(self, widget):
		if pr_AutoConnectCheck.get_active() == True: config.set_goption(3, 1)
		else: config.set_goption(3, 0)

	def on_prPublicComputerCheck_toggled(self, widget):
		if pr_PublicComputerCheck.get_active() == True: 
			config.set_goption(4, 1)
		else: config.set_goption(4, 0)

	def on_prClearDataButton_clicked(self, widget):
		if gtkConfirm.confirm('Do you really want to delete all account data?', d_preferences):
			config.clear_accounts()
			r = 1; t = 0
			for k in config.get_accounts():
				r+=1
			while t < r:
				l_LoginCombo.remove_text(t)
				t+=1
			l_PasswordEntry.set_text('')
			l_RememberPasswordCheck.set_active(False)
			l_RememberPasswordCheck.set_sensitive(False)
			l_MakeDefaultCheck.set_active(False)
			l_MakeDefaultCheck.set_sensitive(False)

	def on_prSecureConnectionsCheck_toggled(self, widget):
		if pr_SecureConnectionsCheck.get_active() == True: config.set_goption(5, 1)
		else: config.set_goption(5, 0)

	def on_prHideToSystemTrayCheck_toggled(self, widget):
		if pr_HideToSystemTrayCheck.get_active() == True: config.set_goption(8, 1)
		else: config.set_goption(8, 0)

	def on_prDownloadOverwriteCheck_toggled(self, widget):
		if pr_DownloadOverwriteCheck.get_active() == True: config.set_goption(7, 1)
		else: config.set_goption(7, 0)

	def on_prDownloadsFolderButton_clicked(self, widget):
		d_downloadsfolderchooser.show()

	def on_prCloseButton_clicked(self, widget):
		d_preferences.hide()

	# Downloads folder chooser (dialog)
	def on_fdOpenFolderButton_clicked(self, widget):
		if debug: printDebug(d_downloadsfolderchooser.get_filename())
		config.set_goption(6, str(d_downloadsfolderchooser.get_filename()))
		pr_DownloadsFolderButton.set_label(str(config.get_goption(6)))
		d_downloadsfolderchooser.hide()

	def on_fdCancelButton_clicked(self, widget):
		d_downloadsfolderchooser.hide()

class Connect(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		global currSProgressbarState, account_info, connection_is_active
		currSProgressbarState = [0.1, 'Connecting']
		if b.login(login, passwd):
			currSProgressbarState = [0.6, 'Logged in']
			account_info = b.userInfo
			connection_is_active = 1
			currSProgressbarState = [0.7, 'Refreshing folder list']
			cMainWindow.refresh_folderList()
			currSProgressbarState = [0.8, 'Refreshing folder contents']
			cMainWindow.refresh_fileList()
			currSProgressbarState = [1.0, 'Connected']
			fb_folderview.grab_focus()
			fb_folderview.set_cursor( (0,), None, 0)
			#global selected_folder; 
			selected_folder = cMainWindow.get_folder_from_path((0,))
			cMainWindow.connected()
		else:
			gtkConfirm.message_error('Invalid login. Please check if your login/password combination is correct.', d_login)
			if debug: printDebug('Could not connect: you provided an invalid login/password or your networking isn\'t working')
		self.stop()
	def stop(self):
		self.stopthread.set()

class AddFolder(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		global currSProgressbarState, selected_folder
		currSProgressbarState = [0.2, 'Adding folder']
		b.createFolder(parent_id=str(selected_folder[1]), name=af_FolderNameEntry.get_text())
		currSProgressbarState = [0.5, 'Refreshing folder list']
		cMainWindow.refresh_folderList()
		currSProgressbarState = [0.8, 'Refreshing folder contents']
		cMainWindow.refresh_fileList()		
		currSProgressbarState = [1.0, 'Done']	
		self.stop()
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()

class RemoveFolder(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		global currSProgressbarState, selected_folder
		currSProgressbarState = [0.2, 'Removing folder']
		b.delete('folder', int(selected_folder[1]))
		currSProgressbarState = [0.5, 'Refreshing folder list']
		#global selected_folder; 
		selected_folder = ['', '']
		cMainWindow.refresh_folderList()
		currSProgressbarState = [0.8, 'Refreshing folder contents']
		cMainWindow.refresh_fileList()		
		currSProgressbarState = [1.0, 'Done']	
		self.stop()
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()

class Upload(threading.Thread):
	stopthread = threading.Event()
	def __init__(self, files_to_upload):
		# files_to_upload is a list of file paths
		self.files_to_upload = files_to_upload
		threading.Thread.__init__ ( self )
		global THREADS

	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		global currSProgressbarState, account_info
		# currSProgressbarState = [0.3, 'Uploading file']
		if debug: printDebug('...uploading file, please be patient!')
		filepaths = {}
		folder_id= selected_folder[1]
		size_of_upload = 0
		for f in self.files_to_upload:
			fName = os.path.split(f)[1]
			filepaths[fName] = f
			size_of_upload += os.path.getsize(f)
		UploadFileProgressThread = UploadFileProgress()
		UploadFileProgressThread.start()
		b.uploadFile(filepaths, folder_id)
		UploadFileProgressThread.stop()
		setThread('Upload')
		space_used = int(account_info['space_used']) + int(size_of_upload)
		account_info['space_used'] = str(space_used)
		cMainWindow.ac_update()
		self.file_to_upload = None
		currSProgressbarState = [0.3, 'Refreshing folder contents']
		cMainWindow.refresh_fileList()
		currSProgressbarState = [1.0, 'Ready']
		self.stop()
	def stop(self):
		self.stopthread.set()
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
	def cancel(self):
		multipart.cancel=1
		self.stop
		
class UploadFileProgress(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		if debug: printDebug('* UploadFileProgress * Started')
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		global currSProgressbarState
		self.stopthread.clear()
		if debug: printDebug('* UploadFileProgress * Progress starting at: %s' % uploadProgress())
		#s_status.push(0,"Uploading file...")
		while not self.stopthread.isSet():
			uProgress = uploadProgress() /100
			currSProgressbarState = [uProgress, 'Uploading file... %s%%' % str(uploadProgress())[:5]]
			#if not uploadProgress() < 100.0:
			#	self.stop()
			time.sleep(0.01)
		if debug: printDebug('* UploadFileProgress * Stopped')
	def stop(self):
		self.stopthread.set()
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		
class DownloadFolder(threading.Thread):
	stopthread = threading.Event()
	folder = None
	def run(self):
		if not self.folder:
			self.stop()
		file_list = []
		folderName, folderID = self.folder
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		global currSProgressbarState
		files_in_folder = b.refresh_fileList(folderID)
		currSProgressbarState = [0.0, 'Starting download'] 
		DownloadFileProgressThread = DownloadFileProgress()
		DownloadFileProgressThread.start()
		try:
			for f in files_in_folder:
				file_list.append(f.id)
			b.downloadMultiple(file_list, path)
			if debug: printDebug('* Success download all file from folder id: %s' % self.folderID)
		except:
			if debug: printDebug('* Could not download one or more files from folder id: %s' % self.folderID)
		DownloadFileProgressThread.stop()
		currSProgressbarState = [1.0, 'Download completed'] 
		self.stop()
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()

class DownloadFile(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		file_list = []
		file_list.append(selected_file.id)
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		global currSProgressbarState
		currSProgressbarState = [0.0, 'Starting download'] 
		DownloadFileProgressThread = DownloadFileProgress()
		DownloadFileProgressThread.start()
		b.downloadMultiple(file_list)
		DownloadFileProgressThread.stop()
		setThread('DownloadFile')
		currSProgressbarState = [1.0, 'Ready'] 
		self.stop()
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()
	def cancel(self):
		b.cancel = 1
		self.stop()

class DownloadFileProgress(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		if debug: printDebug('* DownloadFileProgress * Started')
		global currSProgressbarState
		self.stopthread.clear()
		while not self.stopthread.isSet():
			progress = b.progress()
			if debug: printDebug('percentage is: %s' % b.progress())
			if progress != 0:
				if b.downloadTotal() == 1:
					currSProgressbarState = [(b.progress() / 100), 'Downloading file %s %s' % (str(b.progress())[:5], '%')] 
				elif b.downloadTotal() > 1:
					currSProgressbarState = [(b.progress() / 100), 'Downloading %s/%s %s %s' % (b.downloadPos(), b.downloadTotal(), str(b.progress())[:5], '%')] 
			time.sleep(0.01)
		if debug: printDebug('* DownloadFileProgress * Stopped')

	def stop(self):
		self.stopthread.set()
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()

class DeleteFile(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		if debug: printDebug('* DeleteFile * Started')
		global currSProgressbarState, account_info
		currSProgressbarState = [0.3, 'Deleting file']
		b.delete(target='file', item_id=int(selected_file.id))
		currSProgressbarState = [0.8, 'Refreshing folder contents']
		cMainWindow.refresh_fileList()
		currSProgressbarState = [1.0, 'Done']
		space_used = int(account_info['space_used']) - int(selected_file.size)
		account_info['space_used'] = str(space_used)
		if debug: printDebug(int(selected_file.size) / 1024 / 1024.0)
		cMainWindow.ac_update()
		self.stop()
		if debug: printDebug('* DeleteFile * Stopped')
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()

class MoveFile(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		if debug: printDebug('* MoveFile * Started')
		global currSProgressbarState, active_selected_lock
		currSProgressbarState = [0.3, 'Moving file']
		if selected_file.id and selected_folder[1]:
			b.move('file', selected_file.id, int(selected_folder[1]))
			currSProgressbarState = [0.6, 'Refreshing file contents']
			cMainWindow.refresh_fileList()
			currSProgressbarState = [1.0, 'Done']
		else:
			if debug:
				if not selected_file.id: printDebug('??? selected_file.id: Argument missing')
				if not int(selected_folder[1]): printDebug('??? int(selected_folder[1]): Argument missing')
			currSProgressbarState = [1.0, 'Error while moving!']
		print cMainWindow.files_by_pid[selected_folder[1]]
		active_selected_lock = False
		self.stop()
		if debug: printDebug('* MoveFile * Stopped')
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()

class MoveFolder(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		if debug: printDebug('* MoveFolder * Started')
		global currSProgressbarState, active_selected_lock
		currSProgressbarState = [0.3, 'Moving folder']
		if debug: printDebug('Previously selected folder is: ' + str(prev_selected_folder[1]))
		b.move('folder', int(prev_selected_folder[1]), int(selected_folder[1]))
		currSProgressbarState = [0.6, 'Refreshing folder list']
		cMainWindow.refresh_folderList()
		currSProgressbarState = [1.0, 'Done']
		active_selected_lock = False
		self.stop()
		if debug: printDebug('* MoveFolder * Stopped')
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()

class RenameFile(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		if debug: printDebug('* RenameFile * Started')
		global currSProgressbarState
		currSProgressbarState = [0.3, 'Renaming file']
		b.rename('file', int(selected_file.id), str(rn_NewNameEntry.get_text()))
		currSProgressbarState = [0.7, 'Refreshing folder contents']
		cMainWindow.refresh_fileList()
		currSProgressbarState = [1.0, 'Done']
		self.stop()
		if debug: printDebug('* RenameFile * Stopped')
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()

class RenameFolder(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		if debug: printDebug('* RenameFolder * Started')
		global currSProgressbarState
		currSProgressbarState = [0.3, 'Renaming folder']
		b.rename('folder', int(selected_folder[1]), str(rn_NewNameEntry.get_text()))
		currSProgressbarState = [0.7, 'Refreshing folder list']
		cMainWindow.refresh_folderList()
		currSProgressbarState = [1.0, 'Done']
		self.stop()
		if debug: printDebug('* RenameFolder * Stopped')
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		self.stopthread.set()

class RefreshAll(threading.Thread):
	stopthread = threading.Event()
	def run(self):
		if debug: printDebug('* RefreshAll * Started')
		cMainWindow.offline_menubar()
		cMainWindow.offline_toolbar()
		global currSProgressbarState
		currSProgressbarState = [0.2, 'Refreshing folder list']
		cMainWindow.refresh_folderList()
		currSProgressbarState = [0.7, 'Refreshing folder contents']
		cMainWindow.refresh_fileList()
		currSProgressbarState = [1.0, 'Done']
		self.stop()
	def stop(self):
		cMainWindow.online_menubar()
		cMainWindow.online_toolbar()
		if debug: printDebug('* RefreshAll * Stopped')
		self.stopthread.set()

class SetProgressBar(threading.Thread):
	stopthread = threading.Event()
	currState = [0.0, '']
	def run(self):
		if debug: printDebug('* SetProgressBar * Started')
		global currSProgressbarState
		self.stopthread.clear()
		while not self.stopthread.isSet():
			if currSProgressbarState != self.currState:
				currState = currSProgressbarState
				gtk.gdk.threads_enter()
				s_progress.set_text(currState[1])
				s_progress.set_fraction(currState[0])
				gtk.gdk.threads_leave()
			time.sleep(0.5)
		if debug: printDebug('* SetProgressBar * Stopped')
	def stop(self):
		self.stopthread.set()

def setThread(name, thread=None):
	global THREADS
	THREADS[name] = thread
	if thread==None:
		THREADS['active'] = None
	else:
		THREADS['active'] = name
		
def bytes_to_kbytes(bytes, decimal=None):
	pot = { 0:'B', 1:'KB', 2:'MB', 3:'GB', 4:'TB' }
	i = 0
	while 1:
		if bytes > 1000:
			i += 1
			bytes = bytes / 1024.0
			continue
		break
	bytes = str(bytes)
	if decimal:
		bytes = bytes.split('.')[0] + '.' + bytes.split('.')[1][:decimal]
	return (bytes, pot[i])
	
def printDebug(string):
    dtime=time.localtime()
    string = '(debug)[%s:%s:%s]$ %s' % (dtime[3],dtime[4],dtime[5],str(string))
    print string

class main:
	Application()
	
if __name__ == "__main__":
	main()
